/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * File Name          : freertos.c
 * Description        : Code for freertos applications
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2025 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "cmsis_os.h"
#include "main.h"
#include "task.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "../../User/MAX6675ISA/MAX6675ISA.h"
#include "../../User/button/button.h"
#include "../../User/cmd/dbg_cmd.h"
#include "../../User/cmd/my_queue.h"
#include "../../User/ds18b20/bsp_ds18b20.h"
#include "../../User/my_define.h"
#include "../../User/oled/bsp_oled_debug.h"
#include "../../User/pt100/pt100.h"
#include "adc.h"
#include "stm32f1xx_it.h"
#include "usart.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
osThreadId          defaultTaskHandle;
uint32_t            defaultTaskBuffer[1024];
osStaticThreadDef_t defaultTaskControlBlock;
osThreadId          warring_tHandle;
uint32_t            warring_tBuffer[128];
osStaticThreadDef_t warring_tControlBlock;
osThreadId          sensor1_tHandle;
uint32_t            sensor1_tBuffer[128];
osStaticThreadDef_t sensor1_tControlBlock;
osThreadId          sensor2_tHandle;
uint32_t            sensor2_tBuffer[128];
osStaticThreadDef_t sensor2_tControlBlock;
osThreadId          sensor3_tHandle;
uint32_t            sensor3_tBuffer[128];
osStaticThreadDef_t sensor3_tControlBlock;
osThreadId          concotrl_tHandle;
uint32_t            concotrl_tBuffer[128];
osStaticThreadDef_t concotrl_tControlBlock;
osThreadId          oled_tHandle;
uint32_t            oled_tBuffer[128];
osStaticThreadDef_t oled_tControlBlock;
osThreadId          button_tHandle;
uint32_t            button_tBuffer[128];
osStaticThreadDef_t button_tControlBlock;

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void const* argument);
void warring_f(void const* argument);
void sensor1_f(void const* argument);
void sensor2_f(void const* argument);
void sensor3_f(void const* argument);
void concotrl_f(void const* argument);
void oled_f(void const* argument);
void button_f(void const* argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer, StackType_t** ppxIdleTaskStackBuffer, uint32_t* pulIdleTaskStackSize);

/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t  xIdleStack[configMINIMAL_STACK_SIZE];

void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer, StackType_t** ppxIdleTaskStackBuffer, uint32_t* pulIdleTaskStackSize)
{
    *ppxIdleTaskTCBBuffer   = &xIdleTaskTCBBuffer;
    *ppxIdleTaskStackBuffer = &xIdleStack[0];
    *pulIdleTaskStackSize   = configMINIMAL_STACK_SIZE;
    /* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY */

/**
 * @brief  FreeRTOS initialization
 * @param  None
 * @retval None
 */
void MX_FREERTOS_Init(void)
{
    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* USER CODE BEGIN RTOS_MUTEX */
    /* add mutexes, ... */
    /* USER CODE END RTOS_MUTEX */

    /* USER CODE BEGIN RTOS_SEMAPHORES */
    /* add semaphores, ... */
    /* USER CODE END RTOS_SEMAPHORES */

    /* USER CODE BEGIN RTOS_TIMERS */
    /* start timers, add new ones, ... */
    /* USER CODE END RTOS_TIMERS */

    /* USER CODE BEGIN RTOS_QUEUES */
    /* add queues, ... */
    /* USER CODE END RTOS_QUEUES */

    /* Create the thread(s) */
    /* definition and creation of defaultTask */
    osThreadStaticDef(defaultTask, StartDefaultTask, osPriorityRealtime, 0, 1024, defaultTaskBuffer, &defaultTaskControlBlock);
    defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

    /* definition and creation of warring_t */
    osThreadStaticDef(warring_t, warring_f, osPriorityRealtime, 0, 128, warring_tBuffer, &warring_tControlBlock);
    warring_tHandle = osThreadCreate(osThread(warring_t), NULL);

    /* definition and creation of sensor1_t */
    osThreadStaticDef(sensor1_t, sensor1_f, osPriorityNormal, 0, 128, sensor1_tBuffer, &sensor1_tControlBlock);
    sensor1_tHandle = osThreadCreate(osThread(sensor1_t), NULL);

    /* definition and creation of sensor2_t */
    osThreadStaticDef(sensor2_t, sensor2_f, osPriorityNormal, 0, 128, sensor2_tBuffer, &sensor2_tControlBlock);
    sensor2_tHandle = osThreadCreate(osThread(sensor2_t), NULL);

    /* definition and creation of sensor3_t */
    osThreadStaticDef(sensor3_t, sensor3_f, osPriorityNormal, 0, 128, sensor3_tBuffer, &sensor3_tControlBlock);
    sensor3_tHandle = osThreadCreate(osThread(sensor3_t), NULL);

    /* definition and creation of concotrl_t */
    osThreadStaticDef(concotrl_t, concotrl_f, osPriorityRealtime, 0, 128, concotrl_tBuffer, &concotrl_tControlBlock);
    concotrl_tHandle = osThreadCreate(osThread(concotrl_t), NULL);

    /* definition and creation of oled_t */
    osThreadStaticDef(oled_t, oled_f, osPriorityBelowNormal, 0, 128, oled_tBuffer, &oled_tControlBlock);
    oled_tHandle = osThreadCreate(osThread(oled_t), NULL);

    /* definition and creation of button_t */
    osThreadStaticDef(button_t, button_f, osPriorityRealtime, 0, 128, button_tBuffer, &button_tControlBlock);
    button_tHandle = osThreadCreate(osThread(button_t), NULL);

    /* USER CODE BEGIN RTOS_THREADS */
    /* add threads, ... */
    /* USER CODE END RTOS_THREADS */
}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
 * @brief  Function implementing the defaultTask thread.
 * @param  argument: Not used
 * @retval None
 */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const* argument)
{
    /* USER CODE BEGIN StartDefaultTask */
    static char cmd_rxd;
    HAL_UART_Receive_IT(&huart1, &hal_uart1_rx, 1);
    init_queue(&rxd_queue);
    dbg_cmd_init(1);
    /* Infinite loop */
    for (;;)
    {
        while (out_queue(&rxd_queue, &cmd_rxd) != QUEUE_EMPTY)
        {
            dbg_cmd_rxd(cmd_rxd);
        }
        // printf("defaultTask\r\n");
        osDelay(pdMS_TO_TICKS(300));
    }
    /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_warring_f */
/**
 * @brief Function implementing the warring_t thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_warring_f */
void warring_f(void const* argument)
{
    /* USER CODE BEGIN warring_f */
    /* Infinite loop */
    for (;;)
    {
        if (machine.threshold_select == SENSOR_DS18B20)
        {
            if (machine.ds18b20_temperature > machine.ds18b20_threshold + 5)
            {
                machine.wrarning_flag = 1;
            }
            else if (machine.ds18b20_temperature < machine.ds18b20_threshold - 5)
            {
                machine.wrarning_flag = 1;
            }
            else
            {
                machine.wrarning_flag = 0;
            }
        }
        if (machine.threshold_select == SENSOR_Kcouple_KCouple)
        {
            if (machine.Kcouple_temperature > machine.Kcouple_threshold + 5)
            {
                machine.wrarning_flag = 1;
            }
            else if (machine.Kcouple_temperature < machine.Kcouple_threshold - 5)
            {
                machine.wrarning_flag = 1;
            }
            else
            {
                machine.wrarning_flag = 0;
            }
        }
        if (machine.threshold_select == SENSOR_ADC_PT100)
        {
            if (machine.pt100_temperature > machine.pt100_threshold + 5)
            {
                machine.wrarning_flag = 1;
            }
            else if (machine.pt100_temperature < machine.pt100_threshold - 5)
            {
                machine.wrarning_flag = 1;
            }
            else
            {
                machine.wrarning_flag = 0;
            }
        }
        //        if (machine.wrarning_flag == 1)
        //        {
        //            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
        //            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
        //        }
        //        else
        //        {
        //            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
        //            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
        //        }
        osDelay(pdMS_TO_TICKS(500));
    }
    /* USER CODE END warring_f */
}

/* USER CODE BEGIN Header_sensor1_f */
/**
 * @brief Function implementing the sensor1_t thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_sensor1_f */
void sensor1_f(void const* argument)
{
    /* USER CODE BEGIN sensor1_f */
    while (DS18B20_Init())
    {
    };
    DS18B20_ReadId(machine.ds18b20_id);
    /* Infinite loop */
    for (;;)
    {
        machine.ds18b20_temperature++;
        // taskENTER_CRITICAL();
        // {
        machine.ds18b20_temperature = machine.pt100_temperature + 0.01;
        // = DS18B20_GetTemp_MatchRom(machine.ds18b20_id);
        //		safe_printf("%f-%x-%x\n",machine.ds18b20_temperature,machine.c1,machine.c2);
        //    GPIO_InitTypeDef GPIO_InitStruct = { 0 };
        //    GPIO_InitStruct.Pin              = GPIO_PIN_6;
        //    GPIO_InitStruct.Mode             = GPIO_MODE_OUTPUT_PP;
        //    GPIO_InitStruct.Pull             = GPIO_NOPULL;
        //    GPIO_InitStruct.Speed            = GPIO_SPEED_FREQ_HIGH;
        //    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
        //					while(1)
        //					{
        //					DS18B20_gpio_test();
        //					}
        // }
        // taskEXIT_CRITICAL();
        // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);
        //   osDelay(pdMS_TO_TICKS(1));
        // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET);
        // osDelay(pdMS_TO_TICKS(10));

        // DS18B20_gpio_test();
        osDelay(pdMS_TO_TICKS(10));
    }
    /* USER CODE END sensor1_f */
}

/* USER CODE BEGIN Header_sensor2_f */
/**
 * @brief Function implementing the sensor2_t thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_sensor2_f */
void sensor2_f(void const* argument)
{
    /* USER CODE BEGIN sensor2_f */
    /* Infinite loop */
    for (;;)
    {
        Kcouple_ReadTemperature(&machine.Kcouple_temperature);
        osDelay(pdMS_TO_TICKS(1000));
    }
    /* USER CODE END sensor2_f */
}

/* USER CODE BEGIN Header_sensor3_f */
/**
 * @brief Function implementing the sensor3_t thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_sensor3_f */
void sensor3_f(void const* argument)
{
    /* USER CODE BEGIN sensor3_f */
    int i = 0;
    /* Infinite loop */
    for (;;)
    {
        HAL_ADC_Start(&hadc1);  // 启动转换
        if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK)
        {
            machine.pt100_adc_value = HAL_ADC_GetValue(&hadc1);  // 读取结果
        }
        HAL_ADC_Stop(&hadc1);  // 停止转换
        for (i = 0; i < 19; i++)
        {
            machine.pt100_adc_queue[i] = machine.pt100_adc_queue[i + 1];
        }
        machine.pt100_adc_queue[19] = machine.pt100_adc_value;
        machine.pt100_adc_sum      = 0;
        for (i = 0; i < 20; i++)
        {
            machine.pt100_adc_sum += machine.pt100_adc_queue[i];
        }
        machine.pt100_adc_avg          = machine.pt100_adc_sum / 10;
        machine.pt100_oumu             = machine.pt100_adc_avg * 0.0297 + 84.388;
        machine.pt100_temperature = get_pt100_temp(machine.pt100_oumu);
        osDelay(pdMS_TO_TICKS(50));
    }
    /* USER CODE END sensor3_f */
}

/* USER CODE BEGIN Header_concotrl_f */
/**
 * @brief Function implementing the concotrl_t thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_concotrl_f */
void concotrl_f(void const* argument)
{
    /* USER CODE BEGIN concotrl_f */
    /* Infinite loop */
    for (;;)
    {
        if (machine.threshold_select == SENSOR_DS18B20)
        {
            if (machine.ds18b20_temperature > machine.ds18b20_threshold + 5)
            {
                machine.contral_up_flag   = 1;
                machine.contral_down_flag = 0;
            }
            else if (machine.ds18b20_temperature < machine.ds18b20_threshold - 5)
            {
                machine.contral_up_flag   = 0;
                machine.contral_down_flag = 1;
            }
            else
            {
                machine.contral_up_flag   = 0;
                machine.contral_down_flag = 0;
            }
        }
        if (machine.threshold_select == SENSOR_Kcouple_KCouple)
        {
            if (machine.Kcouple_temperature > machine.Kcouple_threshold + 5)
            {
                machine.contral_up_flag   = 1;
                machine.contral_down_flag = 0;
            }
            else if (machine.Kcouple_temperature < machine.Kcouple_threshold - 5)
            {
                machine.contral_up_flag   = 0;
                machine.contral_down_flag = 1;
            }
            else
            {
                machine.contral_up_flag   = 0;
                machine.contral_down_flag = 0;
            }
        }
        if (machine.threshold_select == SENSOR_ADC_PT100)
        {
            if (machine.pt100_temperature > machine.pt100_threshold + 5)
            {
                machine.contral_up_flag   = 1;
                machine.contral_down_flag = 0;
            }
            else if (machine.pt100_temperature < machine.pt100_threshold - 5)
            {
                machine.contral_up_flag   = 0;
                machine.contral_down_flag = 1;
            }
            else
            {
                machine.contral_up_flag   = 0;
                machine.contral_down_flag = 0;
            }
        }
        if (machine.contral_up_flag == 1)
        {
            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
        }
        else
        {
            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
        }
        if (machine.contral_down_flag == 1)
        {
            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
        }
        else
        {
            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
        }
        osDelay(pdMS_TO_TICKS(500));
    }
    /* USER CODE END concotrl_f */
}

/* USER CODE BEGIN Header_oled_f */
/**
 * @brief Function implementing the oled_t thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_oled_f */
void oled_f(void const* argument)
{
    /* USER CODE BEGIN oled_f */
    OLED_Init();
    OLED_Fill(0x00);  //
                      /* Infinite loop */
    for (;;)
    {
        //			oled_i2c_test();
        if (machine.state == STATE_RUNNING)
        {
            OLED_ShowStr(0, 0, (unsigned char*)"RUNNING...", 1);
        }
        else
        {
            OLED_ShowStr(0, 0, (unsigned char*)"SETTING...", 1);
        }
        sprintf(machine.ds18b20_str, "DS18B20=%.3f", machine.ds18b20_temperature);
        OLED_ShowStr(0, 1, (unsigned char*)machine.ds18b20_str, 1);
        sprintf(machine.Kcouple_str, "Kcouple=%.3f", machine.Kcouple_temperature);
        OLED_ShowStr(0, 2, (unsigned char*)machine.Kcouple_str, 1);
        sprintf(machine.pt100_str, "pt100  =%.3f", machine.pt100_temperature);
        OLED_ShowStr(0, 3, (unsigned char*)machine.pt100_str, 1);
        if (machine.threshold_select == SENSOR_DS18B20)
        {
            sprintf(machine.ds18b20_threshold_str, "DS18B20 UP=%.0f<-", machine.ds18b20_threshold);
            OLED_ShowStr(0, 4, (unsigned char*)machine.ds18b20_threshold_str, 1);
        }
        else
        {
            sprintf(machine.ds18b20_threshold_str, "DS18B20 UP=%.0f  ", machine.ds18b20_threshold);
            OLED_ShowStr(0, 4, (unsigned char*)machine.ds18b20_threshold_str, 1);
        }
        if (machine.threshold_select == SENSOR_Kcouple_KCouple)
        {
            sprintf(machine.Kcouple_threshold_str, "Kcouple UP=%.0f<-", machine.Kcouple_threshold);
            OLED_ShowStr(0, 5, (unsigned char*)machine.Kcouple_threshold_str, 1);
        }
        else
        {
            sprintf(machine.Kcouple_threshold_str, "Kcouple UP=%.0f  ", machine.Kcouple_threshold);
            OLED_ShowStr(0, 5, (unsigned char*)machine.Kcouple_threshold_str, 1);
        }
        if (machine.threshold_select == SENSOR_ADC_PT100)
        {
            sprintf(machine.pt100_threshold_str, "pt100   UP=%.0f<-", machine.pt100_threshold);
            OLED_ShowStr(0, 6, (unsigned char*)machine.pt100_threshold_str, 1);
        }
        else
        {
            sprintf(machine.pt100_threshold_str, "pt100   UP=%.0f  ", machine.pt100_threshold);
            OLED_ShowStr(0, 6, (unsigned char*)machine.pt100_threshold_str, 1);
        }
    }
    /* USER CODE END oled_f */
}

/* USER CODE BEGIN Header_button_f */
/**
 * @brief Function implementing the button_t thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_button_f */
void button_f(void const* argument)
{
    /* USER CODE BEGIN button_f */
    button_setup();
    /* Infinite loop */
    for (;;)
    {
        button_loop();
        osDelay(pdMS_TO_TICKS(20));
    }
    /* USER CODE END button_f */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */
